package controller

import (
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"github.com/gin-gonic/gin"
	"golang.org/x/net/context"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"math"
	"net/http"
	"time"
	"xunjian/Models"
)

// 存储 TLS 证书过期信息的结构体（针对 kubernetes.io/tls 类型）
type TlsCertExpirationInfo struct {
	Namespace     string    `json:"namespace"`
	SecretName    string    `json:"secretName"`
	ExpireTime    time.Time `json:"expireTime"`
	IsExpired     bool      `json:"isExpired"`
	DaysRemaining int       `json:"daysRemaining"`
	DNSNames      []string  `json:"dnsNames"`
	CommonName    string    `json:"commonName"`
}

// 存储频繁重启的Pod信息
type RestartPodInfo struct {
	Namespace       string `json:"namespace"`
	PodName         string `json:"podName"`
	RestartCount    int32  `json:"restartCount"`
	LastRestartTime string `json:"lastRestartTime"`
}

// 存储k8s节点CPU和内存，用于k8s节点资源使用情况
type NodeResourceUsage struct {
	Name        string  `json:"name"`
	CPUUsage    float64 `json:"cpuUsage"`    // 单位：核（如 0.5 = 500m）
	MemoryUsage float64 `json:"memoryUsage"` // 单位：GB（如 2.0 = 2Gi）
}

// 存储使用资源CPU大于２C，内存大于６G的pod信息
type HighUsagePod struct {
	Namespace string
	PodName   string
	CPUcores  string // 转换后的CPU核数，便于比较
	MemoryGB  string // 转换后的内存GB，便于比较
}

type XJController struct {
	Models.ClientModel
}

func (xj XJController) XJ(c *gin.Context) {
	//1、获取clientSet客户端
	clientSet, err := xj.ClientModel.ClientSet() // 正确调用方式
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "创建 Kubernetes 客户端失败：" + err.Error(),
		})
		return
	}
	//2获取clientSet客户端
	metricsClient, metricsErr := xj.ClientModel.MetricSet() // 正确调用方式
	if metricsErr != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "创建 Kubernetes 客户端失败：" + metricsErr.Error(),
		})
		return
	}
	//node节点巡检---------------------------------------------------------------------------------------------------------------------------------------------

	nodeList, nodeErr := clientSet.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
	if nodeErr != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "获取node信息失败：" + nodeErr.Error(),
		})
		return
	}
	var nodesInfo []map[string]interface{}
	now := time.Now().Format("2006-01-02 15:04:05")
	for _, node := range nodeList.Items {
		memoryQuantity := node.Status.Capacity.Memory()
		memoryBytes := memoryQuantity.Value() // 返回的是 int64，单位是字节
		// 转换为 GB（1 GB = 1024 * 1024 * 1024 Bytes）
		memoryGB := float64(memoryBytes) / (1024 * 1024 * 1024)
		isReady := false
		for _, condition := range node.Status.Conditions {
			if condition.Type == corev1.NodeReady {
				if condition.Status == corev1.ConditionTrue {
					isReady = true
				}
				// 如果是 False 或 Unknown，则 isReady 保持 false
				break
			}
		}
		nodeInfo := map[string]interface{}{
			"name":             node.Name,
			"kubeletVersion":   node.Status.NodeInfo.KubeletVersion,
			"architecture":     node.Status.NodeInfo.Architecture,
			"containerRuntime": node.Status.NodeInfo.ContainerRuntimeVersion,
			"kernelVersion":    node.Status.NodeInfo.KernelVersion,
			"addresses":        node.Status.Addresses[0].Address,
			"memory":           fmt.Sprintf("%.2fG", memoryGB),
			"CPU":              node.Status.Capacity.Cpu(),
			"ready":            isReady,
		}
		nodesInfo = append(nodesInfo, nodeInfo)
	}
	//k8s节点资源使用情况-----------------------------------------------------------------------------------------------------------------------------------------------
	nodeMetrics, nodeMetricsErr := metricsClient.MetricsV1beta1().NodeMetricses().List(context.TODO(), metav1.ListOptions{})
	if nodeMetricsErr != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "获取node资源使用情况失败：" + nodeMetricsErr.Error(),
		})
		return
	}
	var nodesResourceUsage []NodeResourceUsage
	for _, nodeMetric := range nodeMetrics.Items {
		name := nodeMetric.Name

		// 🟢 CPU: 转为核数（float64）
		cpuQuantity := nodeMetric.Usage.Cpu()
		cpuCores := float64(cpuQuantity.MilliValue()) / 1000.0 // 500m -> 0.5

		// 🟢 Memory: 转为 GB（float64）
		memoryQuantity := nodeMetric.Usage.Memory()
		memoryBytes := memoryQuantity.Value()                   // 单位是字节
		memoryGB := float64(memoryBytes) / (1024 * 1024 * 1024) // 转为 GB

		cpuCoresRounded := math.Round(cpuCores*10) / 10
		memoryGBRounded := math.Round(memoryGB*10) / 10
		// 添加到结果列表
		nodesResourceUsage = append(nodesResourceUsage, NodeResourceUsage{
			Name:        name,
			CPUUsage:    cpuCoresRounded,
			MemoryUsage: memoryGBRounded,
		})
	}
	//ingress证书过期巡检---------------------------------------------------------------------------------------------------------------------------------------------
	secrets, secretsErr := clientSet.CoreV1().Secrets("").List(context.TODO(), metav1.ListOptions{})
	if secretsErr != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "获取 Secret 列表失败:" + secretsErr.Error(),
		})
		return
	}
	var tlsCertInfos []TlsCertExpirationInfo
	for _, secret := range secrets.Items {
		// 只处理TLS类型的Secret
		if secret.Type != corev1.SecretTypeTLS {
			continue
		}

		// 检查证书数据是否存在
		certData, exists := secret.Data[corev1.TLSCertKey]
		if !exists || len(certData) == 0 {
			continue
		}

		// 解析证书
		block, _ := pem.Decode(certData)
		if block == nil || block.Type != "CERTIFICATE" {
			continue
		}

		cert, certErr := x509.ParseCertificate(block.Bytes)
		if certErr != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"success": false,
				"message": "解析证书失败: " + certErr.Error(),
			})
			continue
		}

		// 计算过期信息
		now := time.Now()
		expiresIn := time.Until(cert.NotAfter)
		daysRemaining := int(expiresIn.Hours() / 24)
		isExpired := now.After(cert.NotAfter)

		// 添加到结果集
		info := TlsCertExpirationInfo{
			Namespace:     secret.Namespace,
			SecretName:    secret.Name,
			ExpireTime:    cert.NotAfter,
			IsExpired:     isExpired,
			DaysRemaining: daysRemaining,
			DNSNames:      cert.DNSNames,
			CommonName:    cert.Subject.CommonName,
		}

		tlsCertInfos = append(tlsCertInfos, info)
	}

	//k8s节点命名空间情况-----------------------------------------------------------------------------------------------------------------------------------------------
	var nsInfo []map[string]interface{}
	nameSpaceList, nsErr := clientSet.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
	if nsErr != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "获取node资源使用情况失败：" + nsErr.Error(),
		})
		return
	}
	for _, namespace := range nameSpaceList.Items {
		nsName := namespace.Name
		nsPhase := namespace.Status.Phase
		podList, podErr := clientSet.CoreV1().Pods(nsName).List(context.TODO(), metav1.ListOptions{})
		if podErr != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"success": false,
				"message": fmt.Sprintf("获取命名空间%v下的列表失败：%s", nsName, podErr.Error()),
			})
			return
		}
		podNum := 0
		abnormalPodCount := 0
		for _, pod := range podList.Items {
			phase := string(pod.Status.Phase)
			// 可根据业务需求定义什么是异常，比如：非 Running 都算异常
			if phase != "Running" && phase != "Completed" {
				abnormalPodCount++
			}
			podNum++
		}
		nsInfo = append(nsInfo, map[string]interface{}{
			"name":               nsName,
			"namespace_status":   nsPhase,
			"abnormal_pod_count": abnormalPodCount,
			"podNum":             podNum,
		})

	}

	//k8s pod资源使用情况，CPU大于2C，内存大于6G-----------------------------------------------------------------------------------------------------------------------------------------------

	podList, podErr := metricsClient.MetricsV1beta1().PodMetricses("").List(context.TODO(), metav1.ListOptions{})
	if podErr != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": fmt.Sprintf("获取pod资源使用情况失败%v", podErr.Error()),
		})
		return
	}
	var highCPUPods []HighUsagePod
	var highMemoryPods []HighUsagePod

	for _, pod := range podList.Items {
		namespace := pod.Namespace
		podName := pod.Name
		for _, container := range pod.Containers {
			// ======================
			// CPU 使用量
			// ======================
			CPUUsage := container.Usage.Cpu()
			CPUcores := float64(CPUUsage.MilliValue()) / 1000.0
			// 格式化为小数点后两位，带单位（核）
			cpuCoresFormatted := fmt.Sprintf("%.2f核", CPUcores)

			// ======================
			// 内存 使用量
			// ======================
			memoryUsage := container.Usage.Memory()
			memoryBytes := float64(memoryUsage.Value())
			memoryGB := memoryBytes / (1024 * 1024 * 1024) // 转换为GB
			// 格式化为小数点后两位，带单位（GB）
			memoryGBFormatted := fmt.Sprintf("%.2fGB", memoryGB)
			// ======================
			// 筛选 CPU > 2C
			// ======================
			if CPUcores > 1.0 {
				highCPUPod := HighUsagePod{
					Namespace: namespace,
					PodName:   podName,
					CPUcores:  cpuCoresFormatted,
				}
				highCPUPods = append(highCPUPods, highCPUPod)

			}
			if memoryGB > 6.0 {
				highMemoryPod := HighUsagePod{
					Namespace: namespace,
					PodName:   podName,
					MemoryGB:  memoryGBFormatted,
				}
				highMemoryPods = append(highMemoryPods, highMemoryPod)
			}
		}
	}
	//k8s pod频繁重启，重启次数，最后一次重启时间-----------------------------------------------------------------------------------------------------------------------------------------------
	var restartThreshold int32 = 5 // 重启阈值设为5次
	frequentRestartPods := []RestartPodInfo{}

	// 获取所有命名空间的Pod列表
	allPods, podListErr := clientSet.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
	if podListErr != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "获取Pod列表失败：" + podListErr.Error(),
		})
		return
	}

	for _, pod := range allPods.Items {
		totalRestarts := int32(0)
		var lastRestartTime *time.Time

		// 统计所有容器的重启次数
		for _, containerStatus := range pod.Status.ContainerStatuses {
			restarts := containerStatus.RestartCount
			totalRestarts += restarts

			// 获取容器最后终止时间（如果存在）
			if containerStatus.LastTerminationState.Terminated != nil {
				terminatedTime := containerStatus.LastTerminationState.Terminated.FinishedAt.Time

				// 更新最近的重启时间
				if lastRestartTime == nil || terminatedTime.After(*lastRestartTime) {
					lastRestartTime = &terminatedTime
				}
			}
		}

		// 如果重启次数超过阈值，记录信息
		if totalRestarts >= restartThreshold {
			podInfo := RestartPodInfo{
				Namespace:    pod.Namespace,
				PodName:      pod.Name,
				RestartCount: totalRestarts,
			}

			// 格式化最后重启时间
			if lastRestartTime != nil {
				podInfo.LastRestartTime = lastRestartTime.Format("2006-01-02 15:04:05")
			} else {
				podInfo.LastRestartTime = "未知"
			}

			frequentRestartPods = append(frequentRestartPods, podInfo)
		}
	}
	c.HTML(http.StatusOK, "xj.html", gin.H{
		"nodesInfo":           nodesInfo,
		"now":                 now,
		"nodeMetrics":         nodesResourceUsage,
		"nsInfo":              nsInfo,
		"highCPUPods":         highCPUPods,
		"highMemoryPods":      highMemoryPods,
		"frequentRestartPods": frequentRestartPods,
		"tlsCertInfos":        tlsCertInfos,
	})
}

func (xj XJController) PDF(c *gin.Context) {

}
